<?php
/**
* Handles multidimentional array sorting by a key (not recursive)
*
* @author Oliwier Ptak <aleczapka at gmx dot net>
*/
class array_sorter
{
   var $skeys = false;
   var $sarray = false;

   /**
   * Constructor
   *
   * @access public
   * @param mixed $array array to sort
   * @param string $key array key to sort by
   * @param boolean $asc sort order (ascending or descending)
   */
   function array_sorter(&$array, $keys)
   {
       $this->sarray = $array;
       $this->skeys = $keys;
   }

   /**
   * Sort method
   *
   * @access public
   * @param boolean $remap if true reindex the array to rewrite indexes
   */
   function sortit($remap=true)
   {
       $array = &$this->sarray;
       uksort($array, array($this, "_as_cmp"));
       if ($remap)
       {
           $tmp = array();
           while (list($id, $data) = each($array))
               $tmp[] = $data;
           return $tmp;
       }
       return $array;
   }

   /**
   * Custom sort function
   *
   * @access private
   * @param mixed $a an array entry
   * @param mixed $b an array entry
   */
   function _as_cmp($a_idx, $b_idx)
   {
       foreach ($this->skeys as $key)
       {
	   // since uksort will pass here only indexes get real
	   // values from our array
	   if (!is_array($a_idx) && !is_array($b_idx))
	   {
	       $a = $this->sarray[$a_idx][$key[0]];
	       $b = $this->sarray[$b_idx][$key[0]];
	   }

	   if ($key[2])
	   {
		   if ($key[1])
		   {
			   $ret = $key[2]($a, $b);
			   if ($ret != 0) return $ret;
		   }
		   else
		   {
			   $ret = $key[2]($b, $a);
			   if ($ret != 0) return $ret;
		   }
	   }
	   //if string - use string comparision
	   else if (!is_numeric($a) || !is_numeric($b))
	   {
	       if ($key[1])
	       {
		   $ret = strcasecmp($a, $b);
		   if ($ret != 0) return $ret;
	       }
	       else
	       {
		   $ret = strcasecmp($b, $a);
		   if ($ret != 0) return $ret;
	       }
	   }
	   else
	   {
	       if ($key[1])
	       {
		   if (intval($a) > intval($b)) return 1;
		   else if (intval($a) < intval($b)) return -1;
	       }
	       else
	       {
		   if (intval($a) > intval($b)) return -1;
		   else if (intval($a) < intval($b)) return 1;
	       }
	   }
       }

       return 0;
   }

}//end of class

function multi_sort(&$array, $keys, $asc=true, $remap=false)
{
	for ($i = 0; $i < count($keys); ++$i)
	{
		if (!is_array($keys[$i]))
		{
			$keys[$i] = array($keys[$i], $asc);
		}
	}
	$sorter = new array_sorter($array, $keys, $asc);
	return $sorter->sortit($remap);
}

?>
